package org.gp.core.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.gp.core.entity.*;
import org.gp.core.entity.constant.Default;
import org.gp.core.entity.dto.ResponseDTO;
import org.gp.core.entity.enums.DTOCodeEnum;
import org.gp.core.entity.enums.HobbyEnum;
import org.gp.core.entity.result.*;
import org.gp.core.exception.BusinessException;
import org.gp.core.mapper.ActivityMapper;
import org.gp.core.service.*;
import org.gp.core.utils.HobbyConvertUtil;
import org.gp.core.web.param.SeekActParam;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 活动信息表  服务实现类
 * </p>
 *
 * @author LuoLiang
 * @since 2017-01-24
 */
@Service
@Slf4j
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {
    @Resource
    private IActivityUserRelationService relationService;
    @Resource
    private ActivityMapper activityMapper;
    @Resource
    private IUserService userService;
    @Resource
    private IBillService billService;
    @Resource
    private ICommentService commentService;
    @Resource
    private IBlacklistService blacklistService;
    @Resource
    private IHobbyService hobbyService;

    private Boolean checkBlackList(Integer userId) {
        EntityWrapper<Blacklist> ew = new EntityWrapper<>();

        ew.where("user_id={0}", userId);
        List<Blacklist> blacklists = blacklistService.selectList(ew);
        if (!CollectionUtils.isEmpty(blacklists)) {
            return true; //不为空返回true
        }
        return false;

    }

    @Override
    public ResponseDTO<SponsorActResult> sponsorActivity(Activity activity) {
        ResponseDTO<SponsorActResult> dto = new ResponseDTO<>();
        SponsorActResult param = new SponsorActResult();

        try {
            //判断用户是否在黑名单当中
            if (checkBlackList(activity.getSponsorUserid())) {
                dto.setCode("1");
                dto.setResMsg("您被加入黑名单中，不能进行此操作");

                return dto;
            }

//            EntityWrapper<Blacklist> ew = new EntityWrapper<>();
//            ew.where("user_id={0}", activity.getSponsorUserid());
//            List<Blacklist> blacklists = blacklistService.selectList(ew);
//            if (!CollectionUtils.isEmpty(blacklists)) {
//                dto.setCode("1");
//                dto.setResMsg("您被加入黑名单中，不能进行此操作");
//            }

            //插入或更新活动
            if (StringUtils.isNotEmpty(activity.getDesn())) {
                activity.setDesn("待管理员审核");
            }
            insertOrUpdate(activity);
            log.info("插入活动信息:{}", JSON.toJSONString(activity));

            //活动添加成功后,发起者自动加入该活动
            EntityWrapper<ActivityUserRelation> entityWrapper = new EntityWrapper<>();
            entityWrapper.where("activity_id={0}", activity.getId());
            entityWrapper.and("user_id", activity.getSponsorUserid());
            ActivityUserRelation userRelation = relationService.selectOne(entityWrapper);
            if (userRelation == null) {//说明用户新发起活动
                this.joinActivity(activity.getSponsorUserid(), activity.getId(), "发起者", "XXXXX");
//                userRelation = new ActivityUserRelation();
//                userRelation.setActivityId(activity.getId());
//                userRelation.setUserId(activity.getSponsorUserid());
//                log.info("发起者自动加入该活动,插入数据:{}", JSON.toJSONString(userRelation));
            }
            relationService.insertOrUpdate(userRelation);

            param.setActId(activity.getId());
            param.setActName(activity.getName());
            dto.setData(param);
            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
        } catch (BusinessException e) {
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("发起活动失败");
            log.error("发起活动业务异常:", e);
        }

        return dto;
    }

    @Override
    public ResponseDTO<List<ActivityResult>> getActListByHobby(SeekActParam param, Integer userId) {
        ResponseDTO<List<ActivityResult>> dto = new ResponseDTO<>();

        //分页参数构造
        Page<Activity> page = new Page<>();
        page.setSize(param.getPageSize());
        page.setCurrent(param.getCurrentPage());

        EntityWrapper<Activity> ew = new EntityWrapper<>();
        log.debug("查询isPass={}的活动", param.getIsPass());
        ew.where("ispass={0}", param.getIsPass());  //添加审批通过的过滤条件
        ew.and("startdate>{0}", DateFormatUtils.format(new Date(), Default.ACTIVITY_TIME_TYPE));
        if (!StringUtils.isEmpty(param.getHobbyNum())) {
            ew.and("label={0}", param.getHobbyNum());
        }
        if (!StringUtils.isEmpty(param.getSearchCondition())) {
            EntityWrapper<User> userEntityWrapper = new EntityWrapper<>();
            userEntityWrapper.where("nickname={0}", param.getSearchCondition());
            User user = userService.selectOne(userEntityWrapper);
            ew.andNew("name={0}", param.getSearchCondition());
            ew.or("place={0}", param.getSearchCondition());
            if (user != null) {
                ew.or("sponsor_userid={0}", user.getId());
            }
        }

        try {
            page = selectPage(page, ew);
            List<Activity> data = page.getRecords();
            if (userId != null) {
                EntityWrapper<Hobby> entityWrapper = new EntityWrapper<>();
                entityWrapper.where("user_id={0}", userId);
                List<Hobby> hobbyList = hobbyService.selectList(entityWrapper);
                if (!CollectionUtils.isEmpty(hobbyList)) {//用户设置过兴趣爱好才进行排序
                    data = HobbyConvertUtil.hobbySort(data, hobbyList.get(0).getHobbyStr());
                }
            }
            List<ActivityResult> activityResults = initActivityResult(data);

            dto.setData(activityResults);
            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
            dto.setResMsg(page.getTotal() + "_" + page.getCurrent());
        } catch (BusinessException e) {
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("获取活动列表失败");
            log.error("获取活动列表业务异常:", e);
        }

        return dto;
    }

    @Override
    public ResponseDTO<List<ActivityDetailResult>> relatedActivity(Integer activityId, Integer sponsorId) {
        ResponseDTO<List<ActivityDetailResult>> dto = new ResponseDTO<>();

        EntityWrapper<Activity> ew = new EntityWrapper<>();
        ew.where("id<>{0}", activityId);
        ew.and("sponsor_userid={0}", sponsorId);
        ew.and("ispass={0}", 0);
        ew.and("startdate>{0}", DateFormatUtils.format(new Date(), Default.ACTIVITY_TIME_TYPE));

        try {
            List<Activity> activities = activityMapper.selectList(ew);
            List<ActivityDetailResult> activityDetailResults = activities.stream().map(activity -> {
                ActivityDetailResult activityDetailResult = this.getActivityDetailInfo(activity.getId()).getData();
                activityDetailResult.setPersonNum("人数：" + activityDetailResult.getPersonNum() + "/" + activityDetailResult.getTotalPersonNum());
                return activityDetailResult;
            }).collect(Collectors.toList());

            dto.setData(activityDetailResults);
            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
        } catch (BusinessException e) {
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("获取活动列表失败");
            log.error("获取活动列表业务异常:", e);
        }

        return dto;
    }

    @Override
    public ResponseDTO<Activity> getActivity(Integer id) {
        ResponseDTO<Activity> dto = new ResponseDTO<>();
        Activity activity = baseMapper.selectById(id);
        activity.setLabel(HobbyConvertUtil.getHobbyKey(activity.getLabel()));
        dto.setData(activity);

        return dto;
    }

    //封装活动列表结果，放入发起人姓名
    private List<ActivityResult> initActivityResult(List<Activity> activities) {
        List<ActivityResult> activityResults = new ArrayList<>(10);
        ActivityResult activityResult = null;
        for (Activity activity : activities) {
            activityResult = new ActivityResult();
            User user = userService.selectById(activity.getSponsorUserid());
            BeanUtils.copyProperties(activity, activityResult);
            activityResult.setLabel(HobbyEnum.HWLX.getDesc(HobbyConvertUtil.
                    getHobbyKey(activity.getLabel())));
            activityResult.setSponsorName(user.getNickname());
            activityResult.setSponsorId(user.getId());

            activityResults.add(activityResult);
        }

        return activityResults;
    }

    @Override
    public ResponseDTO<ActivityDetailResult> getActivityDetailInfo(Integer activityId) {
        ResponseDTO<ActivityDetailResult> dto = new ResponseDTO<>();

        log.info("查询的活动id为：{}", activityId);
        try {
            ActivityDetailResult result = activityMapper.getActivityDetail(activityId);
            log.info("result:{}", JSON.toJSONString(result));
            result.setLabel(HobbyEnum.HWLX.getDesc(HobbyConvertUtil.getHobbyKey(result.getLabel())));   //把code转换为中文含义

            dto.setData(result);
            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
        } catch (BusinessException e) {
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("获取活动详情失败");
            log.error("获取活动详情业务异常:", e);
        }

        return dto;
    }

    /**
     * 查询用户已参加的活动列表
     * todo   根据是否评论查询活动列表
     * flag为COMMENT表示已评论，NOT_COMMENT表示未评论
     *
     * @param userId
     * @return
     */
    @Override
    public ResponseDTO<List<ActivityDetailResult>> getActListByUser(Integer userId, String flag) {
        ResponseDTO<List<ActivityDetailResult>> dto = new ResponseDTO<>();

        Integer code = -1;
        if (flag.equals("COMMENT")) {
            code = 1;
            log.info("用户{}查询已评论列表", userId);
        }
        if (flag.equals("NOT_COMMENT")) {
            code = 0;
            log.info("用户{}查询未评论列表", userId);
        }
        if (flag.equals("NOTPASS")) {
            code = 2;
            log.info("用户{}查询未通过列表", userId);
        }
        try {
            List<ActivityDetailResult> activityResults = activityMapper.getActivityListByUser(userId, code);

            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
            dto.setData(activityResults);
        } catch (BusinessException e) {
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("获取用户活动列表失败");
            log.error("获取用户活动列表业务异常:", e);
        }

        return dto;
    }

    /**
     * 用户加入某活动
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public ResponseDTO joinActivity(Integer userId, Integer activityId, String introduce, String phone) {
        ResponseDTO dto = new ResponseDTO();

        //判断用户是否在黑名单当中
        if (checkBlackList(userId)) {
            dto.setCode("1");
            dto.setResMsg("您被加入黑名单中，不能进行此操作");

            return dto;
        }


        EntityWrapper<ActivityUserRelation> ew = new EntityWrapper<>();
        ew.where("user_id={0}", userId);
        ew.and("activity_id={0}", activityId);
        ActivityUserRelation activityUserRelation = relationService.selectOne(ew);

        if (activityUserRelation != null) {
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("你已加入该活动~");

            return dto;
        } else {
            activityUserRelation = new ActivityUserRelation();
        }

        activityUserRelation.setUserId(userId);
        activityUserRelation.setActivityId(activityId);
        activityUserRelation.setIntroduce(introduce);
        activityUserRelation.setPhone(phone);

        log.info("加入的活动id:{},用户id:{}", activityId, userId);

        try {
            relationService.insert(activityUserRelation);

            Activity activity = activityMapper.selectById(activityId);

            //生成账单信息
            Bill bill = new Bill();
            bill.setActivityId(activityId);
            bill.setUserId(userId);
            bill.setDate(activity.getStartdate());
            bill.setMoney(activity.getBudget());
            bill.setActivityType(HobbyEnum.HWLX.getDesc(HobbyConvertUtil.getHobbyKey(activity.getLabel())));

            billService.insert(bill);

            //生成评论信息
            Comment comment = new Comment();
            comment.setUserId(userId);
            comment.setActivityId(activityId);
            comment.setActivityname(activity.getName());
            comment.setContent("用户暂未填写任何内容");
            comment.setScore(0);
            comment.setSponsorname(userService.selectById(activity.getSponsorUserid()).getNickname());

            commentService.insert(comment);

            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
        } catch (BusinessException e) {
            log.error("加入活动业务异常：", e);
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("加入活动失败");
        }

        return dto;
    }

    @Override
    public ResponseDTO passActivity(Integer activityId, Integer sponsorId) {
        ResponseDTO dto = new ResponseDTO();

        try {
            Activity activity = selectById(activityId);

            activity.setIspass(0);  //设置字段表示该活动已通过
            updateById(activity);

            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
            dto.setResMsg("1");
        } catch (Exception e) {
            log.error("通过活动业务异常：", e);
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("通过活动失败");
        }

        return dto;
    }

    @Override
    public ResponseDTO refuseActivity(Integer activityId, Integer sponsorId, String reason) {
        ResponseDTO dto = new ResponseDTO();

        try {
            Activity activity = selectById(activityId);
            activity.setIspass(1);
            activity.setDesn(reason);
            updateById(activity);

            log.info("拒绝id为{}的活动成功", activityId);
            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
            dto.setResMsg("1");
        } catch (Exception e) {
            log.error("拒绝通过活动业务异常：", e);
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("拒绝通过活动失败");
        }

        return dto;
    }

    @Override
    public ResponseDTO<AdminInfoResult> initAdminInfo() {
        ResponseDTO<AdminInfoResult> dto = new ResponseDTO<>();
        AdminInfoResult adminInfo = new AdminInfoResult();

        try {
            adminInfo.setActivityNumber(selectCount(new EntityWrapper<>()));
            adminInfo.setApplyNumber(commentService.selectCount(new EntityWrapper<>()));

            EntityWrapper<Activity> ew = new EntityWrapper<>();
            ew.where("ispass={0}", 1); //待审核查询条件
            ew.and("startdate>{0}", DateFormatUtils.format(new Date(), Default.ACTIVITY_TIME_TYPE));

            adminInfo.setAuditActivityNumber(selectCount(ew));
            adminInfo.setBlacklistNumber(blacklistService.selectCount(new EntityWrapper<>()));
            adminInfo.setPieData(getPieData());
            adminInfo.setLineData(getLineData());

            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
            dto.setData(adminInfo);
        } catch (Exception e) {
            log.error("获取管理员监控信息业务异常：", e);
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
            dto.setResMsg("获取管理员监控信息失败");
        }

        return dto;
    }

    //管理员获取饼状图业务
    private List<PieData> getPieData() {
        List<CountTypeResult> countTypeResults = activityMapper.countActivityType();

        countTypeResults
                .stream()
                .forEach(countTypeResult -> {
                    countTypeResult.setLabel(HobbyEnum.HWLX.getDesc(HobbyConvertUtil.getHobbyKey(countTypeResult.getLabel())));
                });

        List<PieData> pieDataList = new ArrayList<>(6);

        for (CountTypeResult result : countTypeResults) {
            PieData pieData = new PieData(result.getLabel(), result.getCount());
            pieDataList.add(pieData);
        }

        return pieDataList;
    }

    //管理员获取折线图业务
    private List<LineData> getLineData() {
        List<LineData> lineDataList = new ArrayList<>();

        Map<Integer, Integer> weekMap = new HashMap<>();
        for (int j = 1; j <= 7; j++) {
            weekMap.put(j, 0);
        }

        for (int i = 1; i <= 6; i++) {
            LineData lineData = new LineData();
            lineDataList.add(lineData);

            lineData.setName(HobbyEnum.HWLX.getDesc(HobbyConvertUtil.getHobbyKey(String.valueOf(i))));
            lineData.setType("line");
            lineData.setStack("总量");
            lineData.setAreaStyle(lineData.new AreaStyle());

            activityMapper.countActivityNumByWeek(i)
                    .stream()
                    .forEach(activityWeekNum -> weekMap.put(activityWeekNum.getStartDate(), activityWeekNum.getCount()));
            List<Integer> dataList = new ArrayList<>();
            for (Map.Entry<Integer, Integer> entry : weekMap.entrySet()) {
                dataList.add(entry.getValue());
            }

            lineData.setData(dataList.toArray(new Integer[dataList.size()]));
        }

        return lineDataList;
    }
}
